#include "server.h"
#include <QDataStream>
#include <QtSql>
#include <QDebug>
Server::Server()
{
}

void Server::incomingConnection(qintptr socketDescriptor)
{
    TcpClientSocket* socket= new TcpClientSocket();//建立了一个新的TCP连接用于和客户端的通信
    socket->setSocketDescriptor(socketDescriptor);
    socketlist.append(socket);//将新建立的tCP链接放到list中
    connect(socket,SIGNAL(updateClient(QByteArray,TcpClientSocket*)),this,SLOT(updateClient(QByteArray,TcpClientSocket* )));//将客户端发消息和updateClient这个函数绑定
    connect(socket,SIGNAL(disconnected(TcpClientSocket*)),this,SLOT(slotDisconnected(TcpClientSocket*)));//客户端断开链接和slotDisconnect这个函数绑定
}

//处理接受的信号信息
void Server::updateClient(QByteArray m,TcpClientSocket* n)//m表示发送的数据，n表示对应的socket编号
{
    QDataStream in(&m,QIODevice::ReadOnly);
    quint8 type;
    in>>type;           //客户端发来的信号，根据信号来判断客户端要进行的操作
//客户端发送的数据的内容先是一个大写字母表示要进行什么操作，这些功能应该差不多了
    switch(type){
    case 'L':login(m,n);break;      //收到'L'信号，服务器进行登录处理
    case 'R':regedit(m,n);break;    //收到'R'信号，服务器进行注册处理
    case 'A':add(m,n);break;    //收到'A'信号，服务器进行添加好友/群处理
    case 'D':break;    //收到'D'信号，服务器进行删除好友/群处理
    case 'E':break;    //收到'E'信号，服务器进行修改个人资料，好友备注，群昵称
    case 'M':message(m,n);break;    //收到'M'信号，服务器进行收发单聊/群聊消息处理
    case 'Q':quit(m,n);break;       //收到'Q'信号，服务器进行退出处理
    case 'N':creategroup(m,n);break;                 //收到'N'信号，服务器进行创建群的操作
    case 'S':show(m,n);break;                 //收到'S'信号，服务器进行信息显示操作，包括好友列表显示，消息显示，群列表显示
    }
}

//登录，只是检查密码和用户名
void Server::login(QByteArray m,TcpClientSocket* n){

    //打开数据库


    QString username,passwd;
    bool bRet;
    quint8 type;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    in>>type>>username>>passwd;
    bRet = query1.exec("select u_name, u_password from user;");
    if (!bRet){
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    while(query1.next()){
        if(username == query1.value(0).toString()){
            if(passwd == query1.value(1).toString()){
                //更新在线信息
                QString strUpdateSqlFormat("Update user Set u_userstateid = %1 "
                                           "where u_name = '%2';");
                QString strUpdateSql = strUpdateSqlFormat.arg(1).arg(username);//1表示在线
                qDebug()<<strUpdateSql;
                bRet = query1.exec(strUpdateSql);
                if (!bRet){
                    out  << quint8('D')<<tr("用户状态更新失败");     //D 表示数据库出错
                    out.device()->seek(0);
                    n->write(block);
                    return;
                }
                out  << quint8('P'); //P 表示登录通过
                out.device()->seek(0);
                n->write(block);
                return;
            }
            else{
                out  << quint8('E'); //E 表示密码错误
                out.device()->seek(0);
                n->write(block);
                return;
            }
        }
    }
    out<< quint8('N')<<username; //N 表示用户名不存在
    out.device()->seek(0);
    n->write(block);
    return;
}

//注册
void Server::regedit(QByteArray m,  TcpClientSocket* n){
    //读取数据
    quint8 type;
    QString username,password,contry,province,city,signature;
    int sex;
    QDataStream in(&m,QIODevice::ReadOnly);
    in>>type>>username>>sex>>password>>contry>>province>>city>>signature;
    qDebug()<<"username；"<<username<<sex<<"sex";
    QByteArray block;
    QDataStream out(&block,QIODevice::WriteOnly);//out绑定block,方便放入数据

    bool bRet;
    QSqlQuery query1;
    int u_id=0;
        bRet = query1.exec("select u_name  from user;");
        if (!bRet){
            out << quint8('D')<<QString("select 失败");      //‘D’表示数据库错误
            out.device()->seek(0);//文件指针回到原点
            n->write(block);//将出错的消息返回客户端
            return;
        }
        while(query1.next()){//遍历查询的结果,看看是不是重名了
            if(username == query1.value(0).toString()){
                out << quint8('F')<<username;           //‘F’说明用户已存在
                out.device()->seek(0);
                n->write(block);
                return;
            }
            u_id++;
        }

        QString strInsertSqlFormat("insert into user(u_id,u_name, u_password, u_sex, u_signature)"
                                                        " values('%1', '%2', '%3', '%4','%5');" );
        QString strInsertSql = strInsertSqlFormat.arg(u_id).arg(username).arg(password)
                               .arg(sex).arg(signature);//将新注册的用户的名字添加到数据库的指令
        bRet = query1.exec(strInsertSql);
        if (!bRet){
            out  << quint8('D')<<query1.lastError().text();         //‘D’表示数据库错误
            out.device()->seek(0);
            n->write(block);
            return;
        }
        out << quint8('S');            //‘S’表示注册成功
        out.device()->seek(0);
        n->write(block);
        return;


}

//添加好友
void Server::addfriend(QByteArray m,TcpClientSocket* n){

    QString user,friend_username,beizhu,friend_group;
    int friend_type;
    quint8 type1;
    quint8 type2;
    bool bRet;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    //获取数据
    in>>type1>>type2>>friend_username>>user>>beizhu>>friend_type>>friend_group;
    //自动往friend_group表格中放入组别
    QSqlQuery query1;
    QString select_user_friendgroup=QString();//选择所有用户创建的好友组，算了，还有给编号，不给好友组了
    //查询两个用户对应的id
    int id_user,id_friend;
    QString select_user_id1=QString("select u_id from user where u_name='%1'").arg(user);
    if(!query1.exec(select_user_id1))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_user=query1.value(0).toInt();
    query1.clear();

    QString select_user_id2=QString("select u_id from user where u_name='%1'").arg(friend_username);
    if(!query1.exec(select_user_id2))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_friend=query1.value(0).toInt();
    query1.clear();

    //往friend表中放入数据
    QSqlQuery query2;
    QString insert1=QString("insert into friend(f_friendid,f_userid,f_name,f_friendtypeid) values(%1,%2,'%3',%4);").arg(id_user).arg(id_friend).arg(tr("NULL")).arg(friend_type);
    QString insert2=QString("insert into friend(f_friendid,f_userid,f_name,f_friendtypeid) values(%1,%2,'%3',%4);").arg(id_friend).arg(id_user).arg(beizhu).arg(friend_type);
    query2.exec(insert1);
    bRet=query2.exec(insert2);
    if(!bRet)
    {
        out  << quint8('D')<<query2.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }

    out << quint8('S');            //‘S’表示添加好友成功
    out.device()->seek(0);
    n->write(block);
    return;


}

//发送消息
void Server::message(QByteArray m, TcpClientSocket* n){
//    quint8 type;
//    QString msg,msgfrom,msgto,str;
//    QDataStream in(&m,QIODevice::ReadOnly);
//    in >>type>> msgfrom >> msgto >> msg;
//    QHash<QString,int>::const_iterator get;
//    get=usernamelist.find(msgto);//找到目标用户名字对应的socket编号
//    n=get.value();
//    socketlist[n]->write(m);//发送对应的数据

    quint8 type1;
    quint8 type2;
    QDataStream in(&m,QIODevice::ReadOnly);

    in>>type1>>type2;
    switch(type2){
    case '1':sendsinglemsg(m,n);break;
    case '2':sendgroupmsg(m,n);break;
    }
}

//退出
void Server::quit(QByteArray m, TcpClientSocket* n){
    QString username;
    quint8 type;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    in>>type>>username;
    QString strUpdateSqlFormat("update user set u_userstateid = %1 where u_name = '%2';");

    QString strUpdateSql = strUpdateSqlFormat.arg(0).arg(username);
    qDebug()<<strUpdateSql;
    if(!query1.exec(strUpdateSql)){//执行SQL语句
        printf(query1.lastError().text().toStdString().c_str());
        return ;
    };
    userlist.remove(username);//从在线列表中删除


}

//显示在线好友
void Server::online(QByteArray m, TcpClientSocket* n){
//    quint8 type;
//    QString username;
//    bool bRet;
//    QSqlQuery query1;
//    QByteArray block;
//    QDataStream in(&m,QIODevice::ReadOnly);
//    QDataStream out(&block,QIODevice::WriteOnly);
//    in>>type>>username;
//    usernamelist.insert(username,n);
//    QString online=QString("select username from user_info where state = 'online' and username in (select username from '%1' );").arg(username);
//     bRet = query1.exec(online);
//      if (!bRet) return;
//      out<<quint8('G');
//      while( query1.next() ){
//              out<<query1.value(0).toString();
//      }
//      out<<QString("over");
//      socketlist[n]->write(block);
}

//显示离线好友
void Server::unline(QByteArray m, TcpClientSocket* n){
//    QString username;
//    quint8 type;
//    bool bRet;
//    QSqlQuery query1;
//    QByteArray block;
//    QDataStream in(&m,QIODevice::ReadOnly);
//    QDataStream out(&block,QIODevice::WriteOnly);

//    in>>type>>username;
//    QString unline=QString("select username from user_info where state = 'left' and username in (select username from '%1' );").arg(username);
//     bRet = query1.exec(unline);
//      if (!bRet) return;

//      out<<quint8('G');
//      while( query1.next() ){
//              out<<query1.value(0).toString();
//      }
//      out<<QString("over");
//      socketlist[n]->write(block);
}

//群发消息
void Server::sendtoall(QByteArray m, TcpClientSocket* n)
{
//    QDataStream in(&m,QIODevice::ReadOnly);
//    QString username;
//    quint8 type;

//    in>>type>>username;
//    QString select=QString("select username from user_info where state = 'online' and username in (select username from '%1');").arg(username);
//    QSqlQuery query1;
//    query1.exec(select);

//    while(query1.next())
//    {
//        QHash<QString,int>::const_iterator it;
//        it=usernamelist.find(query1.value(0).toString());
//        n=it.value();
//        socketlist[n]->write(m);

    //    }
}

void Server::add(QByteArray m, TcpClientSocket *n)
{

    quint8 type1;
    quint8 type2;
    QDataStream in(&m,QIODevice::ReadOnly);

    in>>type1>>type2;
    switch(type2){
    case '1':addfriend(m,n);break;
    case '2':addgroup(m,n);break;
    }



}

void Server::show(QByteArray m, TcpClientSocket *n)//显示一些东西
{

    quint8 type1;
    quint8 type2;
    QDataStream in(&m,QIODevice::ReadOnly);

    in>>type1>>type2;
    switch(type2){
    case '1':showavailuser(m,n);break;
    case '2':showfriend(m,n);break;
    case '3':showsinglechat(m,n);break;
    case '4':showaddedgroup(m,n);break;
    case '5':showavailgroup(m,n);break;
    case '6':showgroupchat(m,n);break;
    }

    QString username;
}

void Server::showavailuser(QByteArray m, TcpClientSocket *n)
{
        QString username;
        quint8 type1,type2;
        bool bRet;
        QSqlQuery query1;
        QByteArray block;
        QDataStream in(&m,QIODevice::ReadOnly);
        QDataStream out(&block,QIODevice::WriteOnly);

        in>>type1>>type2>>username;
        qDebug()<<"username:"<<username;
        QString availuser=QString("select u_name from user where u_id not in (select f_friendid from friend where f_userid"
                                  " =(select u_id from user where u_name='%1'))and u_name <> '%1';").arg(username);
         bRet = query1.exec(availuser);
          if (!bRet) return;

          out<<quint8('A');
          while( query1.next() ){
                  out<<query1.value(0).toString();
          }
          out<<QString("over");//结束标记
          n->write(block);
}

void Server::showfriend(QByteArray m, TcpClientSocket *n)//显示当前用户所有好友的简略信息（包括备注，名字，状态）
{
    QString username;
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);

    in>>type1>>type2>>username;
    qDebug()<<"username:"<<username;
    QString availuser=QString("select y.u_name,f_name,us_name from user x join friend on "
                              "(x.u_id=f_userid) join user y on (f_friendid=y.u_id) "
                              "join userstate on (y.u_userstateid=us_id)  where x.u_name='%1';").arg(username);
     bRet = query1.exec(availuser);
      if (!bRet) return;

      out<<quint8('F');
      while( query1.next() ){
              out<<query1.value(0).toString()<<query1.value(1).toString()<<query1.value(2).toString()<<tr("c");
      }
      out<<tr("e")<<tr("e")<<tr("e")<<tr("e");;//结束标记
      n->write(block);


      //这边做一个会让耦合度增大的处理，由于我想实现在线转发，但是我的各个界面用的是不同的socket，所以我就在
      //聊天界面发出刷新好友列表请求(这个会由上层自动触发一次)的时候将其socket和名字放到map中，用于表明这个用户处于在线状态
      userlist.insert(username,n);

}

void Server::sendsinglemsg(QByteArray m, TcpClientSocket *n)//发送消息给好友
{
    QString content,time,fromusername,tousername;
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    in>>type1>>type2>>content>>time>>fromusername>>tousername;
    //查询两个用户的id
    int id_from,id_to;
    QString select_user_id1=QString("select u_id from user where u_name='%1'").arg(fromusername);
    if(!query1.exec(select_user_id1))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_from=query1.value(0).toInt();
    query1.clear();

    QString select_user_id2=QString("select u_id from user where u_name='%1'").arg(tousername);
    if(!query1.exec(select_user_id2))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_to=query1.value(0).toInt();
    query1.clear();
    //将消息插入到message数据库
    QSqlQuery query2;
    QString insert1=QString("insert into messages(m_postmessage,m_time,m_fromuserid,m_touserid) values('%1','%2',%3,%4);").arg(content).arg(time).arg(id_from).arg(id_to);
    qDebug()<<insert1;
    if(!query2.exec(insert1))
        {
            out  << quint8('D')<<query2.lastError().text();
            out.device()->seek(0);
            n->write(block);
            return;
        }
    //将消息转发给目标用户（如果其在线的话），我们这边维护了一个用户在线列表
    if(userlist.contains(tousername))
    {
        out  << quint8('M')<<quint8('1');//M1表示在线的消息
        out<<content<<time<<fromusername<<tousername;
        userlist[tousername]->write(block);
    }

}

void Server::showsinglechat(QByteArray m, TcpClientSocket *n)
{
    QString fromusername,tousername;//
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);

    in>>type1>>type2>>fromusername>>tousername;
    QString chatrecord=QString("select m_postmessage,m_time,x.u_name,y.u_name from messages join user x on(m_fromuserid=x.u_id) "
                               "join user y on(m_touserid=y.u_id) where m_fromuserid=(select u_id from user where u_name='%1') "
                               "and m_touserid=(select u_id from user where u_name='%2') "
                               "or m_fromuserid=(select u_id from user where u_name='%2') and m_touserid=(select u_id from user where u_name='%1') "
                               "order by m_time;").arg(fromusername).arg(tousername);
     bRet = query1.exec(chatrecord);
      if (!bRet) return;

      out<<quint8('M')<<quint8('2');//M2表示加载目标用户的所有消息;
      while( query1.next() ){
          //content,time,fromusername,tousername
            out<<query1.value(0).toString()<<query1.value(1).toString()<<query1.value(2).toString()<<query1.value(3).toString()<<tr("c");
      }
      out<<tr("e")<<tr("e")<<tr("e")<<tr("e")<<tr("e");//结束标记
      n->write(block);
}

void Server::creategroup(QByteArray m, TcpClientSocket *n)
{

    QSqlQuery query1;
    QByteArray block;
    quint8 type1;
    bool bRet;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    QString groupname,ugadminname,createtime,nickname;
    in>>type1>>groupname>>ugadminname>>createtime>>nickname;
    //查询创建者的id
    int id;
    QString select_user_id1=QString("select u_id from user where u_name='%1'").arg(ugadminname);

    if(!query1.exec(select_user_id1))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id=query1.value(0).toInt();
    query1.clear();
    //将创建的群放到user_group中
    //检查是否有重复的名字
    int g_id=0;
        bRet = query1.exec("select ug_name  from user_group;");
        if (!bRet){
            out << quint8('D')<<QString("select 失败");      //‘D’表示数据库错误
            out.device()->seek(0);//文件指针回到原点
            n->write(block);//将出错的消息返回客户端
            return;
        }
        while(query1.next()){//遍历查询的结果,看看是不是重名了
            if(groupname == query1.value(0).toString()){
                out << quint8('F')<<groupname;           //‘F’说明群已存在
                out.device()->seek(0);
                n->write(block);
                return;
            }
            g_id++;
        }
    QString insert1=QString("insert into user_group(ug_id,ug_name, ug_adminid, ug_createtime)"
                                                    " values(%1, '%2', %3, '%4');").arg(g_id).arg(groupname).arg(id).arg(createtime);
    qDebug()<<insert1;
    bRet = query1.exec(insert1);
    if (!bRet){
        out  << quint8('D')<<query1.lastError().text();         //‘D’表示数据库错误
        out.device()->seek(0);
        n->write(block);
        return;
    }
    //将昵称信息放到user_grouptouser表中
    QString insert2=QString("insert into user_grouptouser(ug_userid,ug_groupid, ug_groupnick)"
                                                    " values(%1, %2, '%3');").arg(id).arg(g_id).arg(nickname);
    qDebug()<<insert2;
    bRet = query1.exec(insert2);
    if (!bRet){
        out  << quint8('D')<<query1.lastError().text();         //‘D’表示数据库错误
        out.device()->seek(0);
        n->write(block);
        return;
    }

    out << quint8('S');            //‘S’表示创建成功
    out.device()->seek(0);
    n->write(block);
    return;



}

void Server::showaddedgroup(QByteArray m, TcpClientSocket *n)
{
    QString username;
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);

    in>>type1>>type2>>username;
    qDebug()<<"username:"<<username;
    QString addedgroups=QString("select ug_name from user_group where ug_id in "
                                "(select ug_groupid from user_grouptouser where ug_userid in "
                                "(select u_id from user where u_name='%1'));").arg(username);
     bRet = query1.exec(addedgroups);
      if (!bRet) return;

      out<<quint8('G');
      while( query1.next() ){
              out<<query1.value(0).toString();
              qDebug()<<"groups:"<<query1.value(0).toString();
      }
      out<<tr("e");;//结束标记
      n->write(block);
}

void Server::showavailgroup(QByteArray m, TcpClientSocket *n)//显示所有可以加入的群聊
{
    QString username;
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);

    in>>type1>>type2>>username;
    QString availgroup=QString("select ug_name from user_group where ug_id not in"
                               " (select ug_groupid from user_grouptouser join user on (u_id=ug_userid) "
                               "where u_name='%1');").arg(username);
     bRet = query1.exec(availgroup);
      if (!bRet) return;

      out<<quint8('A');
      while( query1.next() ){
              out<<query1.value(0).toString();
      }
      out<<QString("over");//结束标记
      n->write(block);

}

void Server::addgroup(QByteArray m, TcpClientSocket *n)
{
    QString username,groupname,nickname;
    quint8 type1;
    quint8 type2;
    bool bRet;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    //获取数据
    in>>type1>>type2>>username>>groupname>>nickname;
    //自动往friend_group表格中放入组别
    QSqlQuery query1;
    //查询用户和群聊对应的id
    int id_user,id_group;
    QString select_user_id1=QString("select u_id from user where u_name='%1'").arg(username);
    if(!query1.exec(select_user_id1))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_user=query1.value(0).toInt();
    query1.clear();

    QString select_user_id2=QString("select ug_id from user_group where ug_name='%1'").arg(groupname);
    if(!query1.exec(select_user_id2))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_group=query1.value(0).toInt();
    query1.clear();

    //往friend表中放入数据
    QSqlQuery query2;
    QString insert1=QString("insert into user_grouptouser(ug_userid,ug_groupid,ug_groupnick) values(%1,%2,'%3');").arg(id_user).arg(id_group).arg(nickname);
    bRet=query2.exec(insert1);
    if(!bRet)
    {
        out  << quint8('D')<<query2.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }

    out << quint8('S');            //‘S’表示添加群聊成功
    out.device()->seek(0);
    n->write(block);
    return;


}

void Server::showgroupchat(QByteArray m, TcpClientSocket *n)
{
    QString groupname;//
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);

    in>>type1>>type2>>groupname;
    QString chatrecord=QString("select gm_content,gm_createtime,u_name,ug_name,ug_groupnick from "
                               "user_groupmsgcontent join user_group on (gm_groupid=ug_id)  "
                               "join user on (u_id=gm_fromid) join user_grouptouser on "
                               "(gm_groupid=ug_groupid) where ug_name='%1' and u_id=ug_userid "
                               "order by ug_createtime; ").arg(groupname);//**************
     bRet = query1.exec(chatrecord);
      if (!bRet) return;

      out<<quint8('M')<<quint8('4');//M4表示加载目标群聊的所有消息;
      while( query1.next() ){
          //content,time,username,groupname,nickname
            out<<query1.value(0).toString()<<query1.value(1).toString()<<query1.value(2).toString()<<query1.value(3).toString()<<query1.value(4).toString()<<tr("c");
      }
      out<<tr("e")<<tr("e")<<tr("e")<<tr("e")<<tr("e")<<tr("e");//结束标记
      n->write(block);

}

void Server::sendgroupmsg(QByteArray m, TcpClientSocket *n)
{
    QString content,time,username,groupname,nickname;
    quint8 type1,type2;
    bool bRet;
    QSqlQuery query1;
    QByteArray block;
    QDataStream in(&m,QIODevice::ReadOnly);
    QDataStream out(&block,QIODevice::WriteOnly);
    in>>type1>>type2>>content>>time>>username>>groupname;
    //查询用户和群聊的id
    int id_user,id_group;
    QString select_user_id1=QString("select u_id from user where u_name='%1'").arg(username);
    if(!query1.exec(select_user_id1))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_user=query1.value(0).toInt();
    query1.clear();

    QString select_user_id2=QString("select ug_id from user_group where ug_name='%1'").arg(groupname);
    if(!query1.exec(select_user_id2))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    id_group=query1.value(0).toInt();
    query1.clear();
    //查询用户在群里的昵称
    QString select_user_nickname=QString("select ug_groupnick from user_grouptouser where ug_userid=%1 and ug_groupid=%2;").arg(id_user).arg(id_group);
    if(!query1.exec(select_user_nickname))
    {
        out  << quint8('D')<<query1.lastError().text();
        out.device()->seek(0);
        n->write(block);
        return;
    }
    query1.first();
    nickname=query1.value(0).toString();
    query1.clear();
    //将消息插入到user_messagemsgcontent数据库
    QSqlQuery query2;
    QString insert1=QString("insert into user_groupmsgcontent(gm_content,gm_groupid ,gm_fromid,gm_fromusername ,gm_createtime)"
                            " values('%1',%2,%3,'%4','%5');").arg(content).arg(id_group).arg(id_user).arg(nickname).arg(time);
    qDebug()<<insert1;
    if(!query2.exec(insert1))
        {
            out  << quint8('D')<<query2.lastError().text();
            out.device()->seek(0);
            n->write(block);
            return;
        }
    //将消息转发给目标用户,由于是群，而且这里我也懒得去查库了，直接全部发，让客户端根据情况进行显示
    for(auto socket :userlist.values())
    {
        out  << quint8('M')<<quint8('3');//M3表示在线群的消息
        out<<content<<time<<username<<groupname<<nickname;
        socket->write(block);
    }

}

//离线
void Server::slotDisconnected(TcpClientSocket* n){
    //socketlist.removeAt(n);//啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
}

